﻿using System;
using System.Collections.Generic;
using System.Text;
using Csla;
using System.Data.Odbc;
using MinaspetroLibrary.Configuracoes;
using System.Data;
using Csla.Data;

namespace MinaspetroLibrary.AssociadoPack
{
    public enum TipoDeLista
    {
        Publico,
        Bloqueado,
        Todos,
        TodosAdmin
    }

    [Serializable()]
    public class AssociadoListInfo : ReadOnlyListBase<AssociadoListInfo, AssociadoChildInfo>
    {

        #region Authorization Rules

        public static bool CanGetObject()
        {
            //TODO: Define CanGetObject permission in AssociadoListInfo
            return true;
            //if (Csla.ApplicationContext.User.IsInRole("AssociadoListInfoViewGroup"))
            //	return true;
            //return false;
        }
        #endregion //Authorization Rules

        #region Factory Methods
        private AssociadoListInfo()
        { /* require use of factory method */ }

        public static AssociadoListInfo GetAssociadoListInfo()
        {
            if (!CanGetObject())
                throw new System.Security.SecurityException("Usuário não autorizado a visualizar AssociadoListInfo");
            return DataPortal.Fetch<AssociadoListInfo>(new FilterCriteria());
        }

        public static AssociadoListInfo GetAssociadoListInfo(TipoDeLista tipo)
        {
            if (!CanGetObject())
                throw new System.Security.SecurityException("Usuário não autorizado a visualizar NoticiaListInfo");
            return DataPortal.Fetch<AssociadoListInfo>(new FilterCriteria(tipo));
        }

        public static AssociadoListInfo GetAssociadoListInfo(int indexInicio, int quantidade)
        {
            if (!CanGetObject())
                throw new System.Security.SecurityException("Usuário não autorizado a visualizar AssociadoListInfo");
            return DataPortal.Fetch<AssociadoListInfo>(new FilterCriteria(indexInicio, quantidade));
        }

        public static AssociadoListInfo GetAssociadoListInfo(int indexInicio, int quantidade, TipoDeLista tipo)
        {
            if (!CanGetObject())
                throw new System.Security.SecurityException("Usuário não autorizado a visualizar AssociadoListInfo");
            return DataPortal.Fetch<AssociadoListInfo>(new FilterCriteria(indexInicio, quantidade, tipo));
        }
        #endregion //Factory Methods

        #region Data Access

        #region Filter Criteria
        [Serializable()]
        private class FilterCriteria
        {
            public int IndexInicio = 0;
            public int Quantidade = 0;
            public TipoDeLista Tipo;

            public FilterCriteria()
            {
            }           

            public FilterCriteria(TipoDeLista tipo)
            {
                this.Tipo = tipo;
            }

            public FilterCriteria(int indexInicio, int quantidade)
            {
                this.IndexInicio = indexInicio;
                this.Quantidade = quantidade;
            }

            public FilterCriteria(int indexInicio, int quantidade, TipoDeLista tipo)
            {
                this.IndexInicio = indexInicio;
                this.Quantidade = quantidade;
                this.Tipo = tipo;
            }
        }
        #endregion //Filter Criteria

        #region Data Access - Fetch
        private void DataPortal_Fetch(FilterCriteria criteria)
        {
            RaiseListChangedEvents = false;
            IsReadOnly = false;

            using (OdbcConnection cn = new OdbcConnection(ConfigDatabase.MinaspetroConnection))
            {
                cn.Open();

                ExecuteFetch(cn, criteria);
            }//using

            IsReadOnly = true;
            RaiseListChangedEvents = true;
        }

        private void ExecuteFetch(OdbcConnection cn, FilterCriteria criteria)
        {
            using (OdbcCommand cm = cn.CreateCommand())
            {
                cm.CommandType = CommandType.Text;
                cm.CommandText = GetFetchScript(criteria);

                using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader()))
                {
                    while (dr.Read())
                        this.Add(AssociadoChildInfo.GetAssociadoChildInfo(dr));
                }
            }//using
        }

        private string GetFetchScript(FilterCriteria criteria)
        {
            string strQuery = "SELECT Id, NumControle, RazaoSocial, NomeFantasia, ac.IdTipoCliente, IdEnderecoRevendedor, IdContatoRevendedor, IdEnderecoCorresp, "
                   + "Cnpj, InscEstadual,InscMunicipal, CnpjLojaConv, BandeiraLojaConv, ServOleo, TipoPosto, BandeiraPosto, DataContratoBandeira, "
                   + "NomeContador, EscritorioContador, IdEnderecoContador, IdContatoContador, DataContador, InformanteContador, "
                   + "Observacoes, DataSolicitacao, Publicar, tc.DescTipoCliente "
                   + "FROM associadotb ac LEFT JOIN tipoclientetb tc ON ac.IdTipoCliente = tc.IdTipoCliente";
            
            //será tornado dinâmico em uma 2ª fase
            strQuery += " ORDER BY RazaoSocial ";

            if (criteria.Quantidade != 0)
                strQuery +=" LIMIT " + criteria.IndexInicio + "," + criteria.Quantidade + ";";

            return strQuery;
        }
        #endregion //Data Access - Fetch
        #endregion //Data Access
    }
}
